package com.esil.project.util;

import java.awt.Image;
import java.awt.Toolkit;
import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.ImageIcon;

import stemmer.stemmerTest;

import com.esil.project.descripteurs.Color;
import com.esil.project.descripteurs.Distance;
import com.esil.project.descripteurs.Sobel;


/**Classe permettant l'enregistrement des images dans la bdd
 * @author sophie
 */
public class RemplissageBDD {
	
	static Connection connection;

	public RemplissageBDD() {
	}

	/**Enregistrement des infos dans la table META
	 * @param url
	 * @param largeur
	 * @param hauteur
	 * @param date
	 * @return
	 */
	public static String insertMeta(String url, int largeur, int hauteur, String date) {
		String requete = "insert into indexation.META (url, largeur, hauteur,date) values (\""
				+ url
				+ "\", \""
				+ largeur
				+ "\",\""
				+ hauteur
				+ "\",\""
				+ date
				+ "\")";
		return requete;
	}

	/**Enregistrement des infos dans la table META_KEYWORD
	 * @param tf
	 * @param terme
	 * @param id_k
	 * @param id_m
	 * @return
	 */
	public static String insertMetaKeyword(int tf, String terme, int id_k, int id_m) {
		String requete = "insert into indexation.META_KEYWORD (tf, terme, id_keyword,id_meta) values (\""
				+ tf 
				+ "\", \"" 
				+ terme 
				+ "\",\"" 
				+ id_k 
				+ "\",\"" 
				+ id_m
				+ "\")";
		return requete;
	}

	
	/**Enregistrement des infos dans la table KEYWORD
	 * @param racine
	 * @param df
	 * @return
	 */
	public static String insertKeyword(String racine, int df) {
		String requete = "insert into indexation.KEYWORD (racine, df) values (\""
				+ racine
				+ "\", \""
				+ df
				+ "\")";
		return requete;
	}
	
	
	/**Enregistrement des infos dans la table DESCRIPTEUR
	 * @param nom
	 * @param vecteur
	 * @param dim
	 * @return
	 */
	public static String insertDescripteur(String nom,String vecteur, int dim) {
		String requete = "insert into indexation.DESCRIPTEUR (nom, vecteur, dim) values (\""
				+ nom
				+ "\", \""
				+ vecteur
				+ "\", \""
				+ dim
				+ "\")";
		return requete;
	}
	
	
	/**Enregistrement dans la table META_DESCRIPTEUR
	 * @param idMeta
	 * @param idDesc
	 * @return
	 */
	public static String insertMetaDescripteur(int idMeta, int idDesc) {
		String requete = "insert into indexation.META_DESCRIPTEUR (id_meta, id_descripteur) values (\""
				+ idMeta
				+ "\", \""
				+ idDesc
				+ "\")";
		return requete;
	}
	
	/**Enregistrement dans la table DISTANCE
	 * @param id1
	 * @param id2
	 * @param dist
	 * @return
	 */
	public static String insertDistance(int id1,int id2, float dist){
		String requete = "insert into indexation.DISTANCE (id_desc1, id_desc2, value) values (\""
				+ id1
				+ "\", \""
				+ id2
				+ "\", \""
				+ dist
				+ "\")";
		return requete;	
	}
	
	/**On reccupre les informations de l'image ncessaires  l'enregistrement dans
	 * la table META, puis on enregistre
	 * @param nom_fichier 
	 * @return 
	 */
	public static int EnregistrementImage(String nom_fichier){
			
		// Rcupration de la taille de l'image
		Toolkit tk = Toolkit.getDefaultToolkit();
		Image image = tk.getImage("WebContent/images/" + nom_fichier);
		image = new ImageIcon(image).getImage();
		int width = image.getWidth(null);
		int height = image.getHeight(null);
		
		
		
		//insertion de l'image dans la table meta				
		try {
			
			String req=insertMeta("WebContent/images/" + nom_fichier,width ,height,"");
			//System.out.println(req);
			connection.createStatement().executeUpdate(req);	
			
			
			//on renvoi l'id de l'image
			String sql = "SELECT id FROM indexation.META WHERE url='WebContent/images/" + nom_fichier+"' ";
			ResultSet resultset;
			resultset = connection.createStatement().executeQuery(sql);
			resultset.next();
			return (resultset .getInt(1));
		} 
		catch (SQLException e) {
			e.printStackTrace();
			return -1;
		}			
	}

	
	
	
	public static int EnregistrementImageUpload(String nom_fichier,String cheminfinal){
	
		
		Toolkit tk = Toolkit.getDefaultToolkit();
		Image image = tk.getImage(cheminfinal + nom_fichier);
		image = new ImageIcon(image).getImage();
		int width = image.getWidth(null);
		int height = image.getHeight(null);
				
		//insertion de l'image dans la table meta				
		try {
			
			String req=insertMeta("WebContent/images/" + nom_fichier,width ,height,"");
			//System.out.println(req);
			connection.createStatement().executeUpdate(req);	
			
			
			//on renvoi l'id de l'image
			String sql = "SELECT id FROM indexation.META WHERE url='WebContent/images/" + nom_fichier+"' ";
			ResultSet resultset;
			resultset = connection.createStatement().executeQuery(sql);
			resultset.next();
			return (resultset .getInt(1));
		} 
		catch (SQLException e) {
			e.printStackTrace();
			return -1;
		}			
	}
	
	
	
	
	/**On enregistre le mot racine dans la table KEYWORD ou on augmente le Df
	 * @param mot
	 * @return
	 */
	public static int MotRacine(String mot, String urlStopword,int idMeta){
		 	
		
		stemmerTest stemmer = new stemmerTest(urlStopword);
		Vector v = stemmer.process(mot+"\n");
		
		
		//si la taille est 0 le mot est dans stopwords
		if(v.size()>0)
		{
			String racine=(String) v.elementAt(0);
			//System.out.println("racine: " + v.elementAt(0));
		
			//ajout du mot racine dans la table KEYWORD
			String sql = "SELECT * FROM indexation.KEYWORD WHERE racine='" +racine +"' ";
			ResultSet resultset;	
			int idKeyword=-1;
			try {
				resultset = connection.createStatement().executeQuery(sql);
				
				//si le mot est dj dans la bdd 
				if(resultset.next()){
					idKeyword=resultset .getInt(1);
					
					//si c'est pour le même mot on ne fait rien
					sql = "SELECT tf FROM indexation.META_KEYWORD WHERE (id_keyword='" +idKeyword +"' AND id_meta='"+idMeta+"')";
					ResultSet resultset2 = connection.createStatement().executeQuery(sql);			
					if(resultset2.next())
						return -idKeyword;
					
					
					//sinon on augmente le df
					int df=resultset .getInt(3);
					df++;
					idKeyword=resultset .getInt(1);
					sql = "UPDATE indexation.KEYWORD SET df='"+df+"' WHERE racine='" +racine +"' ";							
					connection.createStatement().executeUpdate(sql);
				}
		
				//sinon on l'ajoute
				else{
					connection.createStatement().executeUpdate(insertKeyword(racine,1));
				
					//on garde l'id du mot racine
					sql = "SELECT id FROM indexation.KEYWORD WHERE racine='" +racine +"' ";
					resultset = connection.createStatement().executeQuery(sql);			
					resultset.next();
					idKeyword=resultset .getInt(1);
				}
			}
			catch (SQLException e) {				
				e.printStackTrace();
			}
			return idKeyword;			
		}
		else
			return -1;
	}
	
	/**Enregistrement du mot cl et de sa racine
	 * @param mot
	 * @param idMeta
	 */
	public static void EnregistrementMotCle(String mot, int idMeta, String urlStopword){
		
		//recherche du mot racine correspondant
		int idKeyword=MotRacine(mot,urlStopword,idMeta);	
		
		if(idKeyword!=-1){
			//ajout du terme dans la table META_KEYWORD avec l'id du KEYWORD 
			//et l'id de l'image correspondants
			try {
				
				if(idKeyword<-1){
					idKeyword=-idKeyword;
					String sql = "SELECT tf FROM indexation.META_KEYWORD WHERE (id_keyword='" +idKeyword +"' AND id_meta='"+idMeta+"')";
					ResultSet resultset = connection.createStatement().executeQuery(sql);			
					resultset.next();
					int tf=resultset .getInt(1);
					tf=tf+1;
					sql = "UPDATE indexation.META_KEYWORD SET tf='"+tf+"' WHERE (id_keyword='" +idKeyword +"' AND id_meta='"+idMeta+"')";							
					connection.createStatement().executeUpdate(sql);
						
				}
				
				else
					connection.createStatement().executeUpdate(insertMetaKeyword(1,mot,idKeyword,idMeta));
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	/**Dans le cas du dossier image existant
	 * on rcupre les mots cls dans le titre de l'image
	 * @param nom_fichier
	 * @param idMeta
	 */
	public static void SeparationMotsCles(String nom_fichier, int idMeta){
		//sparation des mots cles
		String mots[]=nom_fichier.split("\\+",20);
		
		for(int j=0; j<mots.length-1;j++)
			EnregistrementMotCle(mots[j], idMeta,"");		
	}
	
	
	public static void SeparationMotsClesUpload(String nom_fichier, int idMeta,String urlStopword){
		//sparation des mots cles
		String mots[]=nom_fichier.split(" ",20);
		
		for(int j=0; j<mots.length-1;j++)
			EnregistrementMotCle(mots[j], idMeta,urlStopword);		
	}
	
	/**Calcul des vecteurs couleurs et des distances correspondantes
	 * @param nom_fichier
	 * @param idMeta
	 */
	public static void Couleurs(String nom_fichier, int idMeta, String chemin){
		
		try{
			
			//calcul des vecteurs des couleurs pour remplir la table descripteur
			Color h = new Color(chemin+"WebContent/images/" + nom_fichier, 64);
			
			//insertion dans la table descripteur
			connection.createStatement().executeUpdate(insertDescripteur("couleur",h.getString(),64));
	
			//on garde l'id du descripteur couleur
			String sql = "SELECT id FROM indexation.DESCRIPTEUR WHERE vecteur='" +h.getString() +"' ";
			ResultSet resultset = connection.createStatement().executeQuery(sql);			
			resultset.next();
			int idCouleur=resultset .getInt(1);
			
			//enregistrement dans la table META_DESCRIPTEUR
			connection.createStatement().executeUpdate(insertMetaDescripteur(idMeta,idCouleur));

			
			//Pour chaque descripteur couleur de la table
			sql = "SELECT id,vecteur FROM indexation.DESCRIPTEUR WHERE nom='couleur'";
			resultset = connection.createStatement().executeQuery(sql);		
			while (resultset.next()){
				int idDesc2=resultset .getInt(1);
				String vecteur2=resultset .getString(2);
			
				//calcul des distances
				Distance d=new Distance (h.getString());
				float dist=d.processDistance(vecteur2);
				
				//enregistrement des distances
				connection.createStatement().executeUpdate(insertDistance(idCouleur,idDesc2,dist));
				connection.createStatement().executeUpdate(insertDistance(idDesc2,idCouleur,dist));
			}
		}
		catch(SQLException e) {
			e.printStackTrace();}
	}

	
	/**Calcul des vecteurs sobel et des distaces correspondantes
	 * @param nom_fichier
	 * @param idMeta
	 */
	public static void Sobels(String nom_fichier, int idMeta, String chemin){
		
		try{
			//calcul des vecteur des "sobel"
			Sobel c = new Sobel(chemin+"WebContent/images/" + nom_fichier);
	
			//insertion dans la table descripteur
			connection.createStatement().executeUpdate(insertDescripteur("sobel",c.getString(),0));
			
			//on garde l'id du descripteur
			String sql = "SELECT id FROM indexation.DESCRIPTEUR WHERE vecteur='" +c.getString() +"' ";
			ResultSet resultset = connection.createStatement().executeQuery(sql);			
			resultset.next();
			int idSobel=resultset .getInt(1);
			connection.createStatement().executeUpdate(insertMetaDescripteur(idMeta,idSobel));
		
			
			//Pour chaque descripteur sobel de la table
			sql = "SELECT id,vecteur FROM indexation.DESCRIPTEUR WHERE nom='sobel'";
			resultset = connection.createStatement().executeQuery(sql);		
			while (resultset.next()){
				int idDesc2=resultset .getInt(1);
				String vecteur2=resultset .getString(2);
			
				//calcul des distances
				Distance d=new Distance (c.getString());
				float dist=d.processDistance(vecteur2);
				
				//enregistrement des distances
				connection.createStatement().executeUpdate(insertDistance(idSobel,idDesc2,dist));
				connection.createStatement().executeUpdate(insertDistance(idDesc2,idSobel ,dist));
			}
		}
		catch(SQLException e) {
			e.printStackTrace();}
	}
	
	
	public void EnregistrementUpload(String nom_fichier,String motscle){
		//File fichier = new File("WebContent/images/"+nom_fichier);
		
		
		ConnexionBDD connexionBDD = new ConnexionBDD();
		//Connection connection;		
		
		try {
			connection = connexionBDD.initConnection();

			/*
			 * Test d'interaction avec la base
			 */
			if (!connection.isClosed()) {
				//System.out.println("connexion reussie");
				
				
				File destination=new File("");
				String Array[]=destination .getAbsolutePath().split("/");		
				
				String cheminfinal="";
				for(int i=0; i<Array .length -4;i++)
					cheminfinal+=Array [i]+"/";
						
				//cheminfinal+="/workspace/multimedia_search_engine/WebContent/images/";
				String cheminImage=cheminfinal+"/workspace/multimedia_search_engine/WebContent/images/";
				String cheminStopword=cheminfinal+"/workspace/multimedia_search_engine/";
				
				System.out.println("WebContent/images/" + nom_fichier);	
				int idmeta=EnregistrementImageUpload(nom_fichier,cheminImage);				
				if(idmeta!=-1){
					SeparationMotsClesUpload(motscle,idmeta,cheminStopword);
					//("fin mots clés");
					Couleurs(nom_fichier,idmeta,cheminStopword);
					//System.out.println("fin couleurs");
					Sobels(nom_fichier,idmeta,cheminStopword);
				}
				
				
				
				connection.createStatement().close();
			} 
			else
				System.out.println("Echec de la connexion");
			connection.close();
		}
		catch(Exception e){System.out.println(e);}
		
		
		
		
	}
		
	
	
	/**Lecture des images du dossier images
	 */
	public static void LectureImage(){
			
		// Lecture du dossier images contenant l'ensemble des images du
		// corpus
		File repertoire = new File("WebContent/images");
		String[] listefichiers;
		listefichiers = repertoire.list();
		
		//enregistrement de chaque image dans la BDD
		for (String nom_fichier : listefichiers) {	
			
			if(!nom_fichier.endsWith(".svn")){
				if(!nom_fichier.endsWith(".DS_Store")){
			System.out.println("WebContent/images/" + nom_fichier);					
			int idmeta=EnregistrementImage(nom_fichier);				
			if(idmeta!=-1){
				SeparationMotsCles(nom_fichier,idmeta);
				Couleurs(nom_fichier,idmeta,"");
				Sobels(nom_fichier,idmeta,"");
			}}
			}			
		}
	}

	public static void main(String[] args) {

		//Connexion  la bdd
		ConnexionBDD connexionBDD = new ConnexionBDD();
		//Connection connection;		
		
		try {
			connection = connexionBDD.initConnection();

			/*
			 * Test d'interaction avec la base
			 */
			if (!connection.isClosed()) {
				System.out.println("connexion  la BDD russie");
				LectureImage();				
				connection.createStatement().close();
			} 
			else
				System.out.println("Echec de la connexion");
			connection.close();
			
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

	}
}
